package server;

import httplib.HTTPProtocol;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * The ServerThread class handles one client request-response
 * The thread is then destroyed.
 * @author Denis Zgonjanin
 *
 */
public class ServerThread implements Runnable{
	
	private Socket socket = null;
	private String request;
	private boolean busy;
	public boolean needed;
	private Object lock;
	
	public ServerThread(Object lock){
		this.busy = false;
		this.needed = true;
		this.lock = lock;
	}
	
	/**
	 * The run method. Should not be called directly. Call start() instead
	 * The thread is ran and waits until there is a request which it can process
	 * Once a request has arrived, the thread processes it and then returns to
	 * an idle state
	 */
	public void run(){
		//The thread will wait for requests as long as we need it to
		while(needed){
			//Wait until a socket is received by this thread
			while (socket == null){
				try{
					//If no socket, wait
					synchronized(lock){lock.wait();}
				} catch (Exception e){
					System.out.println(e.getMessage());
				}
			}
			//Busy while processing request.
			this.busy = true;
			processRequest();
			this.busy = false;
		}
	}
	
	/**
	 * Set the client socket whose request this thread is going to process
	 * @param socket
	 */
	public void setSocket(Socket socket){
		this.socket = socket;
	}
	
	/**
	 * @return - Is this thread currently processing a request?
	 */
	public boolean getBusy(){
		return this.busy;
	}
	
	/**
	 * Processes a client request
	 * The thread recieves an HTTP request and returns a respose through the socket
	 */
	private void processRequest(){
		String msg;
		try{
			//Normal instream/outstream stuff
			DataOutputStream out = new DataOutputStream(socket.getOutputStream());
			BufferedReader in = 
				new BufferedReader(new InputStreamReader(socket.getInputStream()));
			
			request = "";
			//read the whole request
			while(!(msg = in.readLine()).equals("")){
				request = request.concat(msg) + "\n";
			}
			
			System.out.println(request);
			HTTPProtocol http = new HTTPProtocol();
			byte[] outputLine = http.processInput(request);
			
			//Print the response to the client socket
			out.write(outputLine);
			
			//Cleanup
			out.close();
			in.close();
			socket.close();
			socket = null;
			
		} catch (IOException e){
			System.out.println(e.getMessage());
		}
	}
}
